package LBT2;

import java.util.Arrays;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.NoSuchElementException;


public abstract class ArrayList<T> implements Iterable<T>
{
    private final static int DEFAULT_CAPACITY = 100;
    private final static int NOT_FOUND = -1;

    protected int rear;
    protected T[] list;
    protected int modCount;


    public ArrayList()
    {
        this(DEFAULT_CAPACITY);
    }


    public ArrayList(int initialCapacity)
    {
        rear = 0;
        list = (T[])(new Object[initialCapacity]);
        modCount = 0;
    }


    protected void expandCapacity(){
        list = Arrays.copyOf(list,list.length*2);
    }


    public T removeLast() throws EmptyCollectionException {
        T result = list[rear-1];
        list[rear]=null;
        rear --;
        return result;
    }

    public T removeFirst() throws EmptyCollectionException {
        T result =list[0];
        rear--;
        for(int i = 0; i< rear; i++){
            list[i] = list[i + 1];
        }
        list[rear] = null;
        return result;
    }

    public T remove(T element)
    {
        T result;
        int index = find(element);

        if (index == NOT_FOUND)
            try {
                throw new ElementNotFoundException("ArrayList");
            } catch (ElementNotFoundException e) {
                e.printStackTrace();
            }

        result = list[index];
        rear--;

        for (int scan=index; scan < rear; scan++)
            list[scan] = list[scan+1];

        list[rear] = null;
        modCount++;

        return result;
    }


    public T first() throws EmptyCollectionException
    {
        T result = list[0];
        return result;
    }

    public T last() throws EmptyCollectionException
    {
        T result = list[rear-1];
        return result;
    }

    public int size(){
        return rear;

    }
    public boolean contains(T target)
    {
        return (find(target) != NOT_FOUND);
    }

    private int find(T target)
    {
        int scan = 0;
        int result = NOT_FOUND;

        if (!isEmpty()) {
            while (result == NOT_FOUND && scan < rear)
                if (target.equals(list[scan]))
                    result = scan;
                else
                    scan++;
        }

        return result;
    }


    public boolean isEmpty(){
        if(size() == 0){
            return true;
        }else
            return false;
    }    //：

    @Override
    public String toString(){
        String string = "";
        for (int i = 0;i < rear;i++){
            string += list[i] + " ";
        }
        return string;
    }


    @Override
    public Iterator<T> iterator(){
        return new ArrayListIterator();
    }


    private class ArrayListIterator implements Iterator<T>
    {
        int iteratorModCount;
        int current;


        public ArrayListIterator()
        {
            iteratorModCount = modCount;
            current = 0;
        }
        @Override
        public boolean hasNext() throws ConcurrentModificationException
        {
            if (iteratorModCount != modCount)
                throw new ConcurrentModificationException();

            return (current < rear);
        }

        @Override
        public T next() throws ConcurrentModificationException
        {
            if (!hasNext())
                throw new NoSuchElementException();
            current++;

            return list[current - 1];
        }
        @Override
        public void remove() throws UnsupportedOperationException
        {
            throw new UnsupportedOperationException();
        }

    }

}